#include <iostream>
#include <unistd.h>
#include <vector>
#include "thread.hpp"

//构造线程名称
string GetThreadName()
{
    static int number = 1;
    char name[64];
    snprintf(name, sizeof(name), "Thread-%d", number++);
    return name;
}


//抢票逻辑
int ticket = 10000; // 全局的共享资源
void GetTicket(string name)
{
    while (true)
    {
        if (ticket > 0)
        {
            // 充当抢票花费的时间
            usleep(1000);
            printf("%s get a ticket : %d\n", name.c_str(), ticket);
            ticket--;
        }
        else
        {
            break;
        }
        // 实际情况, 还有后续的动作
    }
}

int main()
{
    string name1 = GetThreadName();
    Thread<string> t1(name1, GetTicket, name1);

    sleep(2);

    string name2 = GetThreadName();
    Thread<string> t2(name2, GetTicket, name2);

    sleep(2);

    string name3 = GetThreadName();
    Thread<string> t3(name3, GetTicket, name3);

    sleep(2);

    string name4 = GetThreadName();
    Thread<string> t4(name4, GetTicket, name4);

    t1.start();
    sleep(2);

    t2.start();
    sleep(2);

    t3.start();
    sleep(2);

    t4.start();
    sleep(2);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    return 0;
}


//任何一个时刻，只允许一个线程正在访问公共资源 --- 临界资源
//只有一部分代码是在访问公共资源, 所以临界资源最终是要被代码访问的, 进程中访问公共资源的代码叫做临界区
//互斥: 任何一个时刻只有1个执行流进入临界区(执行流只能串行了)
//原子性(锁)

//对一个整形变量, ++/--是不是原子的??
//int cnt = 10; cnt--;
//三条汇编语句(vs下查看)
//1.将内存的cnt值读取到寄存器中
//2.对cnt--
//3.写回内存
//认为一条汇编语句就是原子的!
//执行cnt--过程中，多线程访问中, 任意一个汇编语句都可能发生中断，因此认为++/--不是原子的！

//解释上述抢票代码运行之后结果出现负数的情况
//多线程并发访问全部int, 不是原子的，会有数据不一致的并发访问问题

//ticket>0 这个判断本身也是计算, 一定不是原子的，因为由多个步骤构成
//cpu有四个核心功能: 
//算:算术运算
//逻:逻辑运算
//中:处理内外中断
//控:控制单元

//此时ticket值为1, 多个线程判断if都是成立的, 然后进入if语句, 开始串行对ticket--了!

